/*
 * Copyright (C) 2011-present ShenZhen iBOXCHAIN Information Technology Co.,Ltd.
 *
 * All right reserved.
 *
 * This software is the confidential and proprietary
 * information of iBOXCHAIN Company of China.
 * ("Confidential Information"). You shall not disclose
 * such Confidential Information and shall use it only
 * in accordance with the terms of the contract agreement
 * you entered into with iBOXCHAIN inc.
 */
package com.example.wac.shiro.realm;

import com.example.wac.constant.AuthConstant;
import com.example.wac.entity.system.LoginInfo;
import com.example.wac.service.LoginUserService;
import com.example.wac.shiro.entity.LoginUserInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Set;

/**
 * 登录认证鉴权
 *
 * @author JimGong
 * @version v1.0
 * @date 2019年7月16日 下午4:43:09
 */
@Slf4j
public class MyShiroRealm extends AuthorizingRealm {

    @Autowired
    private LoginUserService loginInfoService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        log.info("从数据库获取权限信息");
        LoginUserInfo user = (LoginUserInfo) principals.getPrimaryPrincipal();

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(user.getRoles());
        authorizationInfo.setStringPermissions(user.getPerms());
        return authorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        log.info("开始登录身份验证.");
        String mobile = (String) token.getPrincipal();

        LoginInfo loginInfo = loginInfoService.getLoginInfoByMobile(mobile);
        if (loginInfo == null) {
            throw new UnknownAccountException();
        }

        Set<String> perms = loginInfoService.selectPermsByMobile(mobile);
        Set<String> roles = loginInfoService.selectRoleCodeByMobile(mobile);
        LoginUserInfo userInfo = new LoginUserInfo(loginInfo.getId(), loginInfo.getMobile(), loginInfo.getMchtNo(), loginInfo.getState(),
                loginInfo.getName(),loginInfo.getEmail(), null, loginInfo.getPwdUpdateTime(), perms, roles, null);
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userInfo, loginInfo.getPwd(), getName());
        authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(loginInfo.getSalt()));
        return authenticationInfo;
    }

    /**
     * 超级管理员拥有所有权限
     */
    @Override
    public boolean isPermitted(PrincipalCollection principals, String permission) {
        LoginUserInfo user = (LoginUserInfo) principals.getPrimaryPrincipal();
        return user.getPerms().contains(AuthConstant.SUPER_ADMIN_PERMS) || super.isPermitted(principals, permission);
    }

    /**
     * 超级管理员拥有所有角色
     */
    @Override
    public boolean hasRole(PrincipalCollection principals, String roleIdentifier) {
        LoginUserInfo user = (LoginUserInfo) principals.getPrimaryPrincipal();
        return user.getPerms().contains(AuthConstant.SUPER_ADMIN_PERMS) || super.hasRole(principals, roleIdentifier);
    }

}
